using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace B4ALL.Cache.Indexus
{
    public class CacheManager : IDataCacheManager
    {


        private double? _cacheDurationInHours = null;

        public double CacheDurationInHours
        {
            get
            {
                if (_cacheDurationInHours.HasValue)
                    return _cacheDurationInHours.Value;
                else
                    return Double.NaN;
            }
            set { _cacheDurationInHours = value; }
        }


        #region IDataCacheManager Members

        /// <summary>
        /// Adds an object to the web cache.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public void Add(string key, object value)
        {
            try
            {
                if (value != null)
                {
                    if (_cacheDurationInHours != null)
                        SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Add(key, value, DateTime.Now.AddHours(_cacheDurationInHours.Value));
                    else
                        SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Add(key, value);
                }
            }
            catch (Exception e)
            {
                B4ALL.Exceptions.ExceptionPolicy.HandleException(e, "Critical Error Policy");
            }
        }

        /// <summary>
        /// Adds an object to the web cache.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public void Add(string key, object value, Int32 cacheDurationInHours)
        {
            try
            {
				if (value != null)
					SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Add(key, value, DateTime.Now.AddHours(cacheDurationInHours));
            }
            catch (Exception e)
            {
                B4ALL.Exceptions.ExceptionPolicy.HandleException(e, "Critical Error Policy");
            }
        }

        public void Refresh(String key, Object value)
        {
            try
            {
                if (value != null)
                {
                    if (Get(key) != null)
                        SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Remove(key);

                    Add(key, value);
                }
            }
            catch (Exception e)
            {
                B4ALL.Exceptions.ExceptionPolicy.HandleException(e, "Critical Error Policy");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object Get(string key)
        {
            try
            {                
                return SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Get(key);
            }
            catch (Exception e)
            {
                Exception extended = new Exception(String.Format("B4ALL.Cache.Indexus.Get({0})", key), e);
                B4ALL.Exceptions.ExceptionPolicy.HandleException(extended, "Critical Error Policy");
                return null;
            }
        }

        public object GetRegex(string key)
        {
            try
            {
                IDictionary<String, byte[]> objects = SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.RegexGet(key);
                   
                foreach (KeyValuePair<String, byte[]> keyValue in objects)
                {
                    if (keyValue.Value == null)
                        continue;

                    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    MemoryStream memStream = new MemoryStream(keyValue.Value);
                    return bf.Deserialize(memStream);
                }

                return null;
            }
            catch (Exception e)
            {
                Exception extended = new Exception(String.Format("B4ALL.Cache.Indexus.Get({0})", key), e);
                B4ALL.Exceptions.ExceptionPolicy.HandleException(extended, "Critical Error Policy");
                return null;
            }
        }

        public ICollection<String> GetRegexKeys(string key)
        {
            IDictionary<String, byte[]> objects = SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.RegexGet(key);
            return objects.Keys;
        }

        public void RemoveRegex(string key)
        {
            SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.RegexRemove(key);
        }

        public void Remove(String key)
        {
            SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Remove(key);
        }

        public void Clear()
        {
            SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache.SharedCache.Clear();
        }

        #endregion

    }
}
